/**
 * All rights Reserved, Designed By www.tydic.com
 *
 * @Title: LoginFilter.java
 * @Package com.yyn.security.config.filter
 * @Description:
 * @author: yuyanan
 * @date: 2018年10月19日
 * @version V1.0
 * @Copyright: yuyanan
 */
package com.luci.security.filter;

import com.alibaba.fastjson.JSON;
import com.luci.config.AuthProperties;
import com.luci.security.result.AuthResultAdapter;
import com.luci.security.result.LoginException;
import com.luci.security.support.ILogin;
import com.luci.security.support.ILoginBo;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * <pre>
 * 登陆拦截器
 * </pre>
 *
 * @author yuyanan
 * @date 2018年10月19日
 */
public class LoginFilter extends AbstractAuthenticationProcessingFilter {

    private AuthProperties authProperties;
    private AuthResultAdapter authResultAdapter;

    /**
     * 登陆接口
     */
    private ILogin iLogin;

    public ILogin getiLogin() {
        return iLogin;
    }

    public void setiLogin(ILogin iLogin) {
        this.iLogin = iLogin;
    }



    /**
     * 初始化要指定认证管理器与securirty支持类
     *
     * @param authenticationManager AuthenticationManager
     */
    public LoginFilter(AuthenticationManager authenticationManager, AuthProperties authProperties, ILogin iLogin, AuthResultAdapter authResultAdapter) {
        super(new AntPathRequestMatcher(authProperties.getLoginUrl(), authProperties.getLoginMethod()));

        this.authResultAdapter = authResultAdapter;

        if (authenticationManager == null) {
            logger.error("LoginFilter init error:no specify AuthenticationManager !");
        }
        if (iLogin == null) {
            logger.error("LoginFilter init error:no specify ILogin Class !");
        }

        // ~ 设置认证管理器
        setAuthenticationManager(authenticationManager);
        // ~ 设置安全支持类
        setiLogin(iLogin);
        // ~ 设置登录成功处理器
        setAuthenticationSuccessHandler(
                (request, response, authentication) -> iLogin.loginSuccess(request, response, authentication));
        // ~ 设置登录失败处理器
        setAuthenticationFailureHandler(
                (request, response, exception) -> iLogin.loginFail(request, response, exception));

        if (logger.isDebugEnabled()) {
            logger.debug("LoginFilter init! url: [" + authProperties.getLoginUrl() + "] allow method [" + authProperties.getLoginMethod() + "]");
        }
    }

    /**
     * 执行登录前的检验
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException {
        ILoginBo loginBo = JSON.parseObject(request.getInputStream(), iLogin.getLoginBoClass());
        if (loginBo == null) {
            logger.error("登陆参数为空");
            throw new LoginException(authResultAdapter.loginFail());
        }
        AbstractAuthenticationToken token = new AbstractAuthenticationToken(null) {
            @Override
            public Object getCredentials() {
                return null;
            }

            @Override
            public Object getPrincipal() {
                return null;
            }
        };
        token.setDetails(loginBo);
        return this.getAuthenticationManager().authenticate(token);
    }

}
